<template>
  <v-dialog v-model="isBindDialogOpen" max-width="566px" persistent>
    <v-card>
      <v-card-title class="pt-5 pl-5 flex flex-row">
        <span class="text-[#736B7D]">{{ t('message.system.bind.title') }}</span>
        <v-spacer />
        <v-icon
          color="gray darken-2"
          class="text-gray-400"
          @click.stop="$emit('update:is-bind-dialog-open', false)"
        >
          mdi-close
        </v-icon>
      </v-card-title>
      <v-tabs
        v-model="tab"
        background-color="transparent"
        color="basil"
        grow
        style="box-shadow: 0 4px 8px -4px rgba(94, 86, 105, 0.42)"
      >
        <v-tab value="dc">
          <discord-icon v-show="tab !== 'dc'" />
          <discord-icon-active v-show="tab === 'dc'" />
          <span
            class="font-weight-medium ml-2 text-[14px] normal-case"
            :class="tab === 'dc' ? 'text-[#2B6FF0]' : 'text-[#736B7D]'"
          >
            {{ t('message.system.bind.dc') }}
          </span>
        </v-tab>
        <v-tab value="tg">
          <telegram-icon v-show="tab !== 'tg'" />
          <telegram-icon-active v-show="tab === 'tg'" />
          <span
            class="font-weight-medium ml-2 text-[14px] normal-case"
            :class="tab === 'tg' ? 'text-[#2B6FF0]' : 'text-[#736B7D]'"
          >
            {{ t('message.system.bind.tg') }}
          </span>
        </v-tab>
      </v-tabs>
      <v-card-text>
        <v-window v-model="tab">
          <v-window-item value="dc" class="flex flex-column w-content">
            <discord class="mt-8 mb-4 self-center" />
            <div
              class="social-title mb-8 font-weight-medium text-[#736B7D] text-[32px] self-center"
            >
              {{ t('message.system.bind.dc') }}
            </div>
            <v-btn
              class="bind-btn mb-4 !text-[white] !text-[14px] self-center"
              flat
              :color="bindInfo.discord === false ? '#2B6FF0' : '#D8D8D8'"
              :disabled="bindInfo.discord === true"
              @click.stop="bindDC"
            >
              {{
                bindInfo.discord === false
                  ? t('message.system.bind.binding')
                  : t('message.system.bind.bound')
              }}
            </v-btn>
            <v-btn
              class="receive-reward-btn !text-[white] !text-[14px] self-center"
              flat
              :color="bindInfo.discord === true ? '#2B6FF0' : '#D8D8D8'"
              :disabled="bindInfo.discord === false"
              @click.stop="openUrl(config.dcBotUrl)"
            >
              {{ t('message.system.bind.reward') }}
            </v-btn>

            <div
              v-show="bindInfo.discord === true"
              class="self-end text-[#2B6FF0] mt-4 mb-9 text-[12px] cursor-pointer"
              @click.stop="onClickWithdraw"
            >
              {{ t('message.dashboard.reward.withdraw') }}
            </div>
          </v-window-item>

          <v-window-item value="tg" class="flex flex-column w-content">
            <telegram class="mt-8 mb-4 self-center" />
            <div
              class="social-title mb-8 font-weight-medium text-[#736B7D] text-[32px] self-center"
            >
              {{ t('message.system.bind.tg') }}
            </div>
            <v-btn
              class="bind-btn mb-4 !text-[white] !text-[14px] self-center"
              flat
              :color="bindInfo.telegram === false ? '#2B6FF0' : '#D8D8D8'"
              :disabled="bindInfo.telegram === true"
              @click.stop="bindTG"
            >
              {{
                bindInfo.telegram === false
                  ? t('message.system.bind.binding')
                  : t('message.system.bind.bound')
              }}
            </v-btn>
            <v-btn
              class="receive-reward-btn !text-[white] !text-[14px] self-center"
              flat
              :color="bindInfo.telegram === true ? '#2B6FF0' : '#D8D8D8'"
              :disabled="bindInfo.telegram === false"
              @click.stop="openUrl(config.tgBotUrl)"
            >
              {{ t('message.system.bind.reward') }}
            </v-btn>
            <div
              v-show="bindInfo.telegram === true"
              class="self-end text-[#2B6FF0] mt-4 mb-9 text-[12px] cursor-pointer"
              @click.stop="onClickWithdraw"
            >
              {{ t('message.dashboard.reward.withdraw') }}
            </div>
          </v-window-item>
        </v-window>
      </v-card-text>
      <v-card-title class="whitespace-pre-line px-8 pt-0 pb-8">
        <div class="text-[14px] text-[#847F8D]">
          {{ t('message.system.bind.binding') }}
          {{ tab === 'dc' ? 'Discord' : 'Telegram'
          }}{{ t('message.system.bind.intro') }}
        </div>
      </v-card-title>
    </v-card>
  </v-dialog>
</template>

<script lang="ts" setup>
import discordIcon from '@/icons/dc-icon.svg';
import discord from '@/icons/dc.svg';
import discordIconActive from '@/icons/dc-icon-active.svg';
import telegramIcon from '@/icons/tg-icon.svg';
import telegramIconActive from '@/icons/tg-icon-active.svg';
import telegram from '@/icons/tg.svg';
import { ref, toRefs, watchEffect, inject, watch } from 'vue';
import UserStore from '@/store/UserStore';
import { bindSocialAccountApi } from '@/api/system/user';
import Dialog from '@/components/dialog/dialog';
import axios from 'axios';
import config from '@/config';
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
import storage from '@/utils/storage';

interface BindInfo {
  telegram: boolean;
  discord: boolean;
}

interface BindProps {
  isBindDialogOpen: boolean;
  bindInfo: BindInfo;
}

const props = withDefaults(defineProps<BindProps>(), {
  isBindDialogOpen: false,
});

const { isBindDialogOpen, bindInfo } = toRefs(props);

const { t } = useI18n();
const router = useRouter();

const emitter = inject('emitter');

// @ts-ignore
const emit = defineEmits<{
  (e: 'update:is-bind-dialog-open', value: boolean): void;
}>();

const tab = ref<null | string>(null);
// @ts-ignore
const items: string[] = ['Discord', 'Telegram'];
const userStore = UserStore();
let oauthWin: any = null;
const previousUrl = null;
const bindBotChannel = ref<string>('');
const flag = ref<boolean>(false);

const openUrl = (url: string) => {
  window.open(url, '__blank');
};

const bindTG = () => {
  console.log('enter bind tg');
  // @ts-ignore
  window.Telegram.Login.auth(
    { bot_id: '5547505264', request_access: 'write', embed: 1 },
    data => {
      console.log('telegram res:', data);
      bindSocialAccountApi({
        accountId: data.id,
        accountName: data.username,
        type: 2,
      })
        .then((res: any) => {
          console.log('bindSocialApi res:', res);
          bindInfo.value.telegram = true;
          Dialog(t('message.system.bind.success'));

          const userInfo = {
            ...userStore.userInfo,
            tgId: res,
          };
          userStore.setUserInfo(userInfo);
        })
        .catch((err: any) => {
          console.log('bind social err:', err);
        });
    }
  );
};

const bindDC = () => {
  window.removeEventListener('message', receiveMessage);
  console.log('enter bind dc');
  const url =
    'https://discord.com/api/oauth2/authorize?client_id=999165256309944330&redirect_uri=https%3A%2F%2Fsdao.win%2Fprofile&response_type=code&scope=identify';
  // window.location.replace(url)

  const newWinHeight = 600;
  const newWinWidth = 600;
  const winWidth = window.screen.availWidth; // 获取屏幕宽度
  const winHeight = window.screen.availHeight; // 获取屏幕高度
  const left = (winWidth - newWinWidth) / 2; // 获取新窗口距离屏幕左侧的位置
  const top = (winHeight - newWinHeight) / 2; // 获取新窗口距离屏幕顶部的位置
  const strWindowFeatures =
    'width=' +
    newWinWidth +
    ',height=' +
    newWinHeight +
    ',left=' +
    left +
    ',top=' +
    top +
    ',toolbar=no,menubar=no,modal=false,alwaysRaised=yes,location=no,status=no';
  if (oauthWin === null || oauthWin.closed) {
    oauthWin = window.open(url, 'newwindow', strWindowFeatures);
    oauthWin.focus();
  } else if (previousUrl !== url) {
    oauthWin = window.open(url, 'newwindow', strWindowFeatures);
    oauthWin.focus();
  } else {
    oauthWin.focus();
  }

  // name:弹出窗口的名字,可不填，用''代替
  // toolbar=no 是否显示工具栏。yes为显示
  // menubar=no 是否显示菜单栏。yes为显示
  // location=no 是否显示地址字段。yes为显示
  // status=no 是否添加状态栏。yes为可以
  // 设置ref属性，优化seo，告诉搜索引擎不对新页面进行爬取
  oauthWin.ref = 'nofollow';
};

/* Make a function to give us configuration for the Discord API */
function make_config(authorization_token) {
  // Define the function
  return {
    // Define "data"
    headers: {
      // Define "headers" of "data"
      authorization: `Bearer ${authorization_token}`, // Define the authorization
    },
  }; // Return the created object
}

const discordAuthorize = async (code: string) => {
  if (code === '') {
    Dialog(t('message.system.bind.dcCode'));
    return;
  }
  if (flag.value === true) {
    return;
  }
  try {
    const tokenResponse = await axios.postForm(
      'https://discord.com/api/oauth2/token',
      {
        client_id: '999165256309944330',
        client_secret: 'vTxV9wUDZN82RoCQTkMD6QDgiKnhiN0x',
        grant_type: 'authorization_code',
        redirect_uri: 'https://sdao.win/profile',
        scope: 'identify',
        code: code + '',
      },
      {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
        },
      }
    );
    console.log('token:', tokenResponse.data.access_token);
    if (tokenResponse.data.access_token) {
      await axios
        .get(
          'https://discord.com/api/users/@me',
          make_config(tokenResponse.data.access_token)
        )
        .then(response => {
          console.log('discord user resp:', response.data);
          console.log('username:', response.data.username);
          const username =
            response.data.username + '#' + response.data.discriminator;
          const id = response.data.id;
          bindSocialAccountApi({
            accountId: id,
            accountName: username,
            type: 1,
          })
            .then((res: any) => {
              console.log('bindSocialApi res:', res);
              bindInfo.value.discord = true;
              Dialog(t('message.system.bind.success'));

              const userInfo = {
                ...userStore.userInfo,
                dcId: res,
              };
              userStore.setUserInfo(userInfo);
              flag.value = true;
            })
            .catch((err: any) => {
              console.log('bind social err:', err);
            });
        })
        .catch(err => {
          console.log('get my information from discord err:', err);
        });
    } else {
      Dialog(t('message.system.bind.fail'));
    }
  } catch (e) {
    console.log('get token from discord err:', e);
  }
};

const receiveMessage = async event => {
  if (event.origin !== import.meta.env.VITE_DOMAIN) {
    return;
  }
  const { data } = event;
  console.log('event data:', data);
  if (typeof data === 'string' && data.includes('code=')) {
    await discordAuthorize(data.substring(6));
    oauthWin.close();
    emit('update:is-bind-dialog-open', false);
    // location.reload()
  }
};

const onClickWithdraw = async () => {
  await storage.setItem('tab', 'Dashboard');
  await router.push({ name: 'Dashboard' });
  emit('update:is-bind-dialog-open', false);
};

window.addEventListener(
  'message',
  async event => await receiveMessage(event),
  false
);

watchEffect(() => {
  const params = window.location.search;
  if (window.opener) {
    window.opener.postMessage(params);
    window.close();
  }
});

// @ts-ignore
emitter.on('botBind', (channel: string) => {
  console.log('bind social account by bot from channel:', channel);
  bindBotChannel.value = channel;
});

watch(
  () => bindBotChannel.value,
  (newVal: string) => {
    if (newVal !== '') {
      tab.value = bindBotChannel.value;
    } else {
      if (!bindInfo.value.discord) {
        tab.value = 'dc';
      } else if (!bindInfo.value.telegram) {
        tab.value = 'tg';
      }
    }
  }
);
</script>

<style lang="scss" scoped>
.text-basil {
  color: #2b6ff0 !important;
}

.receive-reward-btn,
.bind-btn {
  width: 172px;
  height: 46px;
  border-radius: 8px;
}

::v-deep .v-window__container {
  align-items: center;
}
</style>
